package algorithm;
//Used in Sentinel Inc.'s Defensive Driver Prototype
//Programmer: John Casey Marr
//Programmer:
//Programmer: 
//Class CS 411 Professional Workforce Development
import gui.obu.ObuDrivingDisplayPanel;
import gui.obu.ObuDrivingDisplayPanelImpl;
import gui.obu.alerts.SpeedAlert;

import java.sql.SQLException;
import java.util.Calendar;

import database.OBUdata;
import database.OBUdb;

import objects.OBUentry;
import objects.SpeedLog;

public class Speed_Limit{
	
	//Current Speed of the Driver
	//As found in the OBD II or Prototype Database Dataset
	private int current_speed;
	
	//Current Max Speed Limit
	//As found in the OBU's internal Speed Limit Database
	private int speed_limit;
	
	//Last Known Maximum Speed Limit
	private int past_limit;
	
	//Not used in Speed Limit Algorithm
	//Trigger and Event Identification Numbers
	//int trigger_ID=000000;
	//int event_ID=99999999;
	//Current Location
	private double lat;
	private double lon;
	
	//Has the driver been speeding
	private boolean speeding;
	
	//Start and End time of Event
	private long Start;
	private long End;
	
	//Calendar for time
	private Calendar now=Calendar.getInstance();
	private OBUentry myEntry;	
		
	//Captures largest speed violation
	private int violationMaxSpeed;
	
	//GUI Stuff
	private ObuDrivingDisplayPanel window;
	
	public void setWindow(ObuDrivingDisplayPanel window)
	{
		this.window=window;
	}
	
	public Speed_Limit()
	{
		current_speed=0;
		speed_limit=999;
		past_limit=999;
		lat=999.99;
		lon=999.99;
		speeding=false;
		Start=0;
		End=0;
		myEntry = new OBUentry();
		violationMaxSpeed=0;
	}
	
	
	public void compute(OBUdata runtimedb, OBUdb obudatabase, Integer i,Integer driverID)
	{
		//Step 1: Collect Location
		//        Database Call to get current location
		myEntry.setID(i);
		try {
			runtimedb.getOBUEntry(myEntry);
		} catch (java.sql.SQLException mysqlex) {
			System.out.println("Cannot get this entry");
			return;
		}
		//myEntry.display();

		lat=myEntry.getLat();
		lon=myEntry.getLong();
		
		//Step 2: Collect Current Speed
		//        Database Call to get current Speed
		//current_speed=Database.get_Speed();
		current_speed=myEntry.getSpeed();
		
		if(!((ObuDrivingDisplayPanelImpl)window).getDisplay().isDisposed()) {
			((ObuDrivingDisplayPanelImpl)window).getDisplay().asyncExec(new Runnable() {
				public void run() {
					((ObuDrivingDisplayPanelImpl)window).setCurrentSpeed(Integer.toString(current_speed));
				}
			});
		}
		
		//Step 3: Collect Max Speed Limit
		//		  Database Call to get current max speed limit
		//speed_limit=Database.get_Speed_Limit();
		
		try {
			speed_limit = obudatabase.getNewMax(lat,lon);
			System.out.println("I got from the DB: "+ speed_limit);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			System.out.println("Could not get Speed Limit " + e.getMessage());
		}
		
		//If Speed Limit is 0 keep old speed limit
		if(speed_limit==0)
		{
			speed_limit=past_limit;
		}
		
		//Initialize the past_limit
		if (past_limit == 999) {
			past_limit = speed_limit;
		}
		
		if(!((ObuDrivingDisplayPanelImpl)window).getDisplay().isDisposed()) {
			((ObuDrivingDisplayPanelImpl)window).getDisplay().asyncExec(new Runnable() {
				public void run() {
					((ObuDrivingDisplayPanelImpl)window).setSpeedLimit(Integer.toString(speed_limit));
				}
			});
		}
		
		//Step 4: Compare Current to Max Speed Limit
		if(current_speed>speed_limit)
		{
			//Step 4.1: Has the driver been speeding?
			if(!speeding)
			{
				//Step 4.1.1: If the driver has not been speeding throw alert
				//			  Record Start time and set speeding to true
				//Alert
				if(window==null)
				{
					System.out.println("Can Not Add Speed Limit Alert");
				}
				else
				{
					if(!((ObuDrivingDisplayPanelImpl)window).getDisplay().isDisposed()) {
						((ObuDrivingDisplayPanelImpl)window).getDisplay().asyncExec(new Runnable() {
							public void run() {
								((ObuDrivingDisplayPanelImpl)window).addAlert(new SpeedAlert(current_speed,speed_limit));
							}
						});
					}
				}
				now.setTimeInMillis(System.currentTimeMillis());
				Start=now.getTimeInMillis();
				speeding=true;
			}
				//Step 4.1.2: If the Driver has been speeding continue to monitor
			
			//Step 4.2: Has the Maximum Speed Limit changed?
			else if(past_limit!=speed_limit)
			{
				//Step 4.2.1:  If the Speed limit has changed Throw Alert again
				//			   Continue to monitor event (not a new event)
				//alert();
			}
		}
			//Step 4.3: If the driver is not speeding, was he?
		else
		{
		if(speeding)
		{
			//Step 4.3.1: If the driver was speeding but has stop record end time
			//			  Send event report to database, speeding set to false
			now.setTimeInMillis(System.currentTimeMillis());
			End=now.getTimeInMillis();
			//Database.event(Start,End);
			SpeedLog speedevent=new SpeedLog();
			speedevent.setStudentID(driverID);
			// We don't care about location at this point
			speedevent.setLocationID(1);
			speedevent.setDuration(new Integer((int)End-(int)Start));
			speedevent.setCurrSpeed(violationMaxSpeed);
			
			try {
				obudatabase.addSpeedLog(speedevent);
			} catch (java.sql.SQLException sqlex) {
				System.out.println("Could not write speed log to DB!!!!");
			}
			
			speeding=false;
			violationMaxSpeed=0;
		}
			//Step 4.3.2: If the driver was not speeding, continue to monitor
		}
		if(speeding)
		{
			if(violationMaxSpeed<current_speed)
			{
				violationMaxSpeed=current_speed;
			}
		}
		past_limit=speed_limit;
	}
	
	//Testing Code
	/*
	public void test_curspeed(int x)
	{
		current_speed=x;
	}
	public void test_curMaxSpeed(int x)
	{
		speed_limit=x;
	}

	boolean alertGenerated=false;
	
	void alert(){alertGenerated=true;}
	
	public boolean getAlert(){return alertGenerated;}
	
	int getSpeed(){return current_speed;}
//	int getMaxSpeed(){return speed_limit;}*/
}

